
package com.insigma.business.qrcode.soldier._provider.impl;

import com.insigma.business.qrcode.common.service.SequenceGenerator;
import com.insigma.business.qrcode.common.template.BasePagingResponse;
import com.insigma.business.qrcode.common.util.BizCheckUtil;
import com.insigma.business.qrcode.common.util.ResponseUtils;
import com.insigma.business.qrcode.common.vo.BaseDeleteRequest;
import com.insigma.business.qrcode.common.vo.BaseResponse;
import com.insigma.business.qrcode.soldier.dto.SequenceNameConstant;
import com.insigma.business.qrcode.soldier.dto.SoldierDTO;
import com.insigma.business.qrcode.soldier.dto.SoldierOuterLoginAccountDTO;
import com.insigma.business.qrcode.soldier.dto.UserStatusEnum;
import com.insigma.business.qrcode.soldier.dto.gov.BaseProviderImpl;
import com.insigma.business.qrcode.common.template.area.ScenarioCodeEnum;
import com.insigma.business.qrcode.common.template.area.ServiceCallback;
import com.insigma.business.qrcode.soldier.entity.SoldierApplyInfoDO;
import com.insigma.business.qrcode.soldier.entity.SoldierDO;
import com.insigma.business.qrcode.soldier.entity.SoldierOuterLoginAccountDO;
import com.insigma.business.qrcode.soldier.request.*;
import com.insigma.business.qrcode.soldier.service.SoldierApplyInfoService;
import com.insigma.business.qrcode.soldier._provider.SoldierOuterLoginAccountProvider;
import com.insigma.business.qrcode.soldier.service.SoldierOuterLoginAccountService;
import com.insigma.business.qrcode.soldier.service.SoldierService;
import com.insigma.business.qrcode.common.converter.SoldierOuterLoginAccountProviderConverter;
import com.insigma.business.qrcode.common.converter.SoldierProviderConverter;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;


@Slf4j
@Service
@Component("soldierOuterLoginAccountProvider")
public class SoldierOuterLoginAccountProviderImpl extends BaseProviderImpl implements SoldierOuterLoginAccountProvider {

    @Autowired
    private SoldierOuterLoginAccountService soldierOuterLoginAccountService;

    @Autowired
    private SoldierApplyInfoService soldierApplyInfoService;

    @Autowired
    private SoldierService soldierService;

    @Autowired(required = false)
    private SequenceGenerator sequenceGenerator;


    @Override
    public BasePagingResponse<List<SoldierOuterLoginAccountDTO>> searchSoldierOuterLoginAccount(final SoldierOuterLoginAccountSearchRequest searchRequest) {

        final BasePagingResponse<List<SoldierOuterLoginAccountDTO>> basePagingResponse = new BasePagingResponse<>();
        serviceTemplate.execute(basePagingResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(searchRequest, "查询分页SoldierOuterLoginAccount的请求参数不能为空");
            }

            @Override
            public void executeService() {
                final SoldierOuterLoginAccountBSearcher soldierOuterLoginAccountBSearcher = SoldierOuterLoginAccountProviderConverter.convertRequestSO2Searcher(searchRequest);
                final List<SoldierOuterLoginAccountDO> soldierOuterLoginAccountDOList = soldierOuterLoginAccountService.search(soldierOuterLoginAccountBSearcher);
                final List<SoldierOuterLoginAccountDTO> soldierOuterLoginAccountDTOList = SoldierOuterLoginAccountProviderConverter.convertResponseDOList2DTOList(soldierOuterLoginAccountDOList);
                ResponseUtils.buildSuccessPagingResponse(basePagingResponse, soldierOuterLoginAccountDTOList, searchRequest, soldierOuterLoginAccountBSearcher.getTotalCount());
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.SOLDIER_OUTER_LOGIN_ACCOUNT_SEARCH;
            }
        });

        return basePagingResponse;
    }



    @Override
    public BaseResponse<SoldierOuterLoginAccountDTO> getSoldierOuterLoginAccount(final BaseGetRequest baseGetRequest) {

        final BaseResponse<SoldierOuterLoginAccountDTO> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(baseGetRequest, "获取单条SoldierOuterLoginAccount的请求参数不能为空");
                BizCheckUtil.checkNotBlank((String) baseGetRequest.getId(), "id不能为空");
            }

            @Override
            public void executeService() {
                final SoldierOuterLoginAccountDO soldierOuterLoginAccountDO = soldierOuterLoginAccountService.get((String) baseGetRequest.getId());
                final SoldierOuterLoginAccountDTO remoteObj = SoldierOuterLoginAccountProviderConverter.convertResponseDO2DTO(soldierOuterLoginAccountDO);
                ResponseUtils.setupSuccessResponse(baseResponse, remoteObj);
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.SOLDIER_OUTER_LOGIN_ACCOUNT_GET;
            }
        });
        return baseResponse;
    }

    @Override
    public BaseResponse<SoldierOuterLoginAccountDTO> getSoldierOuterLoginAccountBySoldierId(String soldierId) {

        BizCheckUtil.checkNotBlank(soldierId, "手机号不一致，请核实后填写。");

        SoldierOuterLoginAccountDO accountDtoBySoldierId = soldierOuterLoginAccountService.getAccountDtoBySoldierId(soldierId);
        final SoldierOuterLoginAccountDTO remoteObj = SoldierOuterLoginAccountProviderConverter.convertResponseDO2DTO(accountDtoBySoldierId);

        return ResponseUtils.buildSuccessResponse(remoteObj);
    }


    @Transactional
    @Override
    public BaseResponse<String> insertSoldierOuterLoginAccount(final SoldierOuterLoginAccountInsertRequest insertRequest) {

        final BaseResponse<String> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(insertRequest, "新增SoldierOuterLoginAccount的请求参数不能为空");
            }

            @Override
            public void executeService() {
                final SoldierOuterLoginAccountDO soldierOuterLoginAccountDO = SoldierOuterLoginAccountProviderConverter.convertRequestIO2DO(insertRequest);
                soldierOuterLoginAccountService.insert(soldierOuterLoginAccountDO);
                ResponseUtils.setupSuccessResponse(baseResponse, soldierOuterLoginAccountDO.getId());
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.SOLDIER_OUTER_LOGIN_ACCOUNT_INSERT;
            }
        });
        return baseResponse;
    }


    @Override
    public BaseResponse<Integer> updateSoldierOuterLoginAccount(final SoldierOuterLoginAccountUpdateRequest updateRequest) {

        final BaseResponse<Integer> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(updateRequest, "修改SoldierOuterLoginAccount的请求参数不能为空");
                BizCheckUtil.checkNotBlank(updateRequest.getId(), "id不能为空");
                BizCheckUtil.checkNotBlank(updateRequest.getModifierId(), "操作人不能为空");
                BizCheckUtil.checkNotBlank(updateRequest.getModifierType(), "操作人类型不能为空");
            }

            @Override
            public void executeService() {
                SoldierOuterLoginAccountDO soldierOuterLoginAccountDO = SoldierOuterLoginAccountProviderConverter.convertRequestUO2DO(updateRequest);
                Integer affectRowNum = soldierOuterLoginAccountService.update(soldierOuterLoginAccountDO);
                ResponseUtils.setupSuccessResponse(baseResponse, affectRowNum);
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.SOLDIER_OUTER_LOGIN_ACCOUNT_UPDATE;
            }
        });
        return baseResponse;
    }


    @Override
    public BaseResponse<Integer> deleteSoldierOuterLoginAccount(final BaseDeleteRequest deleteRequest) {

        final BaseResponse<Integer> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(deleteRequest, "逻辑删除SoldierOuterLoginAccount的请求参数不能为空");
                BizCheckUtil.checkNotBlank((String) deleteRequest.getId(), "id不能为空");
                BizCheckUtil.checkNotBlank(deleteRequest.getModifierType(), "操作人类型不能为空");
                BizCheckUtil.checkNotBlank((String) deleteRequest.getModifierId(), "操作人不能为空");
            }

            @Override
            public void executeService() {
                final Integer affectRowNum = soldierOuterLoginAccountService.delete((String) deleteRequest.getId(), deleteRequest.getModifierType(), (String) deleteRequest.getModifierId());
                ResponseUtils.setupSuccessResponse(baseResponse, affectRowNum);
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.SOLDIER_OUTER_LOGIN_ACCOUNT_DELETE_LOGICALLY;
            }
        });
        return baseResponse;
    }

    @Override
    public BaseResponse<SoldierDTO> getOrInsertZlbSoldierOfOuterSysSrc(SoldierRegisterByOuterSystemRequest request) {

        BizCheckUtil.checkNotNull(request, "请求不能为空");
        String outerZlbAccountId = request.getOuterZlbAccountId();
        String idCardNo = request.getOuterSysCertNo();
        String aliAccountId = request.getOuterSysAccountId();

        BizCheckUtil.checkNotNull(outerZlbAccountId, "浙里办userid不能为空");
        BizCheckUtil.checkNotNull(idCardNo, "身份证不能为空");

        SoldierOuterLoginAccountDO targetSoldier = getTargetSoldier(request);
        if (targetSoldier == null) {
            targetSoldier = insertNewSolider(request);
        }

        final SoldierOuterLoginAccountDTO accountDTO = SoldierOuterLoginAccountProviderConverter.convertResponseDO2DTO(targetSoldier);

        final SoldierDO soldierDO = soldierService.get(targetSoldier.getSoldierId());
        final SoldierDTO remoteObj = SoldierProviderConverter.convertResponseDO2DTO(soldierDO);

        remoteObj.setOuterAccount(accountDTO);
        remoteObj.setName(accountDTO.getOuterSysNickName());
        return ResponseUtils.buildSuccessResponse(remoteObj);
    }

    private SoldierOuterLoginAccountDO insertNewSolider(SoldierRegisterByOuterSystemRequest request) {
        final SoldierDO soldierDO = buildSoldierDOForRegister(request);
        soldierService.insert(soldierDO);

        final SoldierOuterLoginAccountDO soldierOuterLoginAccountDO = buildOuterAccountForRegister(soldierDO, request);
        soldierOuterLoginAccountService.insert(soldierOuterLoginAccountDO);

        return soldierOuterLoginAccountDO;
    }


    private SoldierDO buildSoldierDOForRegister(final SoldierRegisterByOuterSystemRequest soldierRegisterByOuterSystemRequest) {
        final SoldierDO soldierDO = new SoldierDO();
        soldierDO.setId(sequenceGenerator.genKey(SequenceNameConstant.SOLDIER_ID));
        soldierDO.setAccountName(soldierDO.getId());
        soldierDO.setAvatarRelativeUri(soldierRegisterByOuterSystemRequest.getOuterSysAvatarUrl());
        soldierDO.setPassword("I-am-the-default-pwd");
        soldierDO.setRegisterTerminalType(soldierRegisterByOuterSystemRequest.getRegisterTerminalType());
        soldierDO.setRegisterSource(soldierRegisterByOuterSystemRequest.getRegisterSource());
        soldierDO.setRegisterLatitude(soldierRegisterByOuterSystemRequest.getRegisterLatitude());
        soldierDO.setRegisterLongitude(soldierRegisterByOuterSystemRequest.getRegisterLongitude());
        soldierDO.setLastLoginIp(soldierRegisterByOuterSystemRequest.getLastLoginIp());
        soldierDO.setLastLoginDatetime(soldierRegisterByOuterSystemRequest.getLastLoginDatetime());
        soldierDO.setStatus(UserStatusEnum.ENABLED.name());
        soldierDO.setMobile(soldierDO.getId());

        return soldierDO;
    }


    private SoldierOuterLoginAccountDO buildOuterAccountForRegister(final SoldierDO newSoldierDO, final SoldierRegisterByOuterSystemRequest soldierRegisterByOuterSystemRequest) {
        final SoldierOuterLoginAccountDO soldierOuterLoginAccountDO = new SoldierOuterLoginAccountDO();
        BeanUtils.copyProperties(soldierRegisterByOuterSystemRequest, soldierOuterLoginAccountDO);
        soldierOuterLoginAccountDO.setEnabled(true);
        soldierOuterLoginAccountDO.setSoldierId(newSoldierDO.getId());
        soldierOuterLoginAccountDO.setLastLoginIp(soldierRegisterByOuterSystemRequest.getLastLoginIp());
        soldierOuterLoginAccountDO.setLastLoginDatetime(soldierRegisterByOuterSystemRequest.getLastLoginDatetime());
        soldierOuterLoginAccountDO.setOuterSysType(soldierRegisterByOuterSystemRequest.getOuterSysType());
        soldierOuterLoginAccountDO.setOuterSysAccountId(soldierRegisterByOuterSystemRequest.getOuterSysAccountId());
        soldierOuterLoginAccountDO.setOuterZlbAccountId(soldierRegisterByOuterSystemRequest.getOuterZlbAccountId());
        soldierOuterLoginAccountDO.setOuterSysNickName(soldierRegisterByOuterSystemRequest.getOuterSysNickName());
        soldierOuterLoginAccountDO.setOuterStatus(soldierRegisterByOuterSystemRequest.getOuterStatus());
        soldierOuterLoginAccountDO.setOuterSysAvatarUrl(soldierRegisterByOuterSystemRequest.getOuterSysAvatarUrl());
        soldierOuterLoginAccountDO.setOuterOverview(soldierRegisterByOuterSystemRequest.getOuterOverview());
        return soldierOuterLoginAccountDO;
    }

    private SoldierOuterLoginAccountDO getTargetSoldier(SoldierRegisterByOuterSystemRequest request) {
        SoldierOuterLoginAccountDO byZlbId = soldierOuterLoginAccountService.getByZlbId(request.getOuterZlbAccountId());
        if (byZlbId != null) {
            return byZlbId;
        }

        SoldierOuterLoginAccountDO loginAccountDO = soldierOuterLoginAccountService.getByIdCardNo(request.getOuterSysCertNo());
        if (loginAccountDO != null) {
            return loginAccountDO;
        }
        String aliId = request.getOuterSysAccountId();
        if (Strings.isNotBlank(aliId)) {
            SoldierOuterLoginAccountDO byOuterSysTypeAndUserId = soldierOuterLoginAccountService.getByOuterSysTypeAndUserId(1, aliId);
            if (byOuterSysTypeAndUserId != null) {
                return byOuterSysTypeAndUserId;
            }
        }

        SoldierApplyInfoDO byIdCardNo = soldierApplyInfoService.getByIdCardNo(request.getOuterSysCertNo());
        if (byIdCardNo != null) {
            String soldierId = byIdCardNo.getSoldierId();
            SoldierOuterLoginAccountDO accountDtoBySoldierId = soldierOuterLoginAccountService.getAccountDtoBySoldierId(soldierId);
            return accountDtoBySoldierId;
        }
        return null;
    }

}
